const { chromium } = require('playwright');
const fs = require('fs-extra');
const path = require('path');
const chalk = require('chalk');
const { processImagePaths } = require('../utils/epubParser');

let browser = null;
let isShuttingDown = false;

/**
 * 查找本地 Chrome 浏览器路径
 */
function findChromePath() {
  const possiblePaths = [
    // Windows 常见路径
    'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
    'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
    process.env.LOCALAPPDATA + '\\Google\\Chrome\\Application\\chrome.exe',
    // 其他可能的路径
    'C:\\Users\\' + process.env.USERNAME + '\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe'
  ];
  
  for (const chromePath of possiblePaths) {
    if (fs.existsSync(chromePath)) {
      return chromePath;
    }
  }
  
  return null;
}

/**
 * 启动或获取浏览器实例
 */
async function launchBrowser() {
  if (browser && !browser.isConnected()) {
    browser = null;
  }
  
  if (!browser) {
    try {
      console.log(chalk.gray('🚀 启动 Playwright 浏览器...'));
      browser = await chromium.launch({
        headless: true,
        args: [
          '--no-sandbox',
          '--disable-setuid-sandbox',
          '--disable-dev-shm-usage',
          '--disable-accelerated-2d-canvas',
          '--no-first-run',
          '--no-zygote',
          '--disable-gpu'
        ]
      });
    } catch (error) {
      console.log(chalk.yellow('⚠️  Playwright 内置浏览器启动失败，尝试使用本地 Chrome...'));
      const chromePath = findChromePath();
      if (chromePath) {
        browser = await chromium.launch({
          headless: true,
          executablePath: chromePath,
          args: [
            '--no-sandbox',
            '--disable-setuid-sandbox',
            '--disable-dev-shm-usage',
            '--disable-accelerated-2d-canvas',
            '--no-first-run',
            '--no-zygote',
            '--disable-gpu'
          ]
        });
        console.log(chalk.green('✅ 使用本地 Chrome 浏览器成功'));
      } else {
        throw new Error('无法找到 Chrome 浏览器');
      }
    }
  }
  
  return browser;
}

/**
 * 将单个 HTML 文件转换为 PDF
 * @param {string} htmlFilePath - HTML 文件路径
 * @param {string} outputPdfPath - 输出 PDF 路径
 * @param {Object} options - PDF 选项
 * @returns {Promise<void>}
 */
async function convertSingleHtmlToPdf(htmlFilePath, outputPdfPath, options = {}) {
  let page = null;
  let context = null;
  
  try {
    // 检查输入文件是否存在
    if (!await fs.pathExists(htmlFilePath)) {
      throw new Error(`HTML 文件不存在: ${htmlFilePath}`);
    }
    
    // 确保输出目录存在
    await fs.ensureDir(path.dirname(outputPdfPath));
    
    // 启动或获取浏览器实例
    const browserInstance = await launchBrowser();
    
    // 创建新上下文和页面
    context = await browserInstance.newContext({
      viewport: { width: 1200, height: 800 }
    });
    page = await context.newPage();
    
    // 加载 HTML 文件
    const fileUrl = `file://${path.resolve(htmlFilePath)}`;
    await page.goto(fileUrl, { 
      waitUntil: 'domcontentloaded', // 改为 domcontentloaded 提高速度
      timeout: 15000 // 减少超时时间
    });
    
    // 等待页面完全加载，但减少等待时间
    await page.waitForTimeout(500);
    
    // 设置 PDF 选项
    const pdfOptions = {
      path: outputPdfPath,
      format: options.format || 'A4',
      printBackground: options.printBackground !== false,
      margin: options.margin || {
        top: '1cm',
        right: '1cm',
        bottom: '1cm',
        left: '1cm'
      },
      scale: options.scale || 1.0,
      preferCSSPageSize: options.preferCSSPageSize !== false
    };
    
    // 生成 PDF
    await page.pdf(pdfOptions);
    
  } catch (error) {
    throw new Error(`HTML 转 PDF 失败: ${error.message}`);
  } finally {
    // 清理资源
    if (page) {
      try {
        await page.close();
      } catch (closeError) {
        console.log(chalk.yellow(`⚠️  关闭页面时出错: ${closeError.message}`));
      }
    }
    if (context) {
      try {
        await context.close();
      } catch (closeError) {
        console.log(chalk.yellow(`⚠️  关闭上下文时出错: ${closeError.message}`));
      }
    }
  }
}

/**
 * 将多个 HTML 文件合并转换为一个 PDF
 * @param {string[]} htmlFilePaths - HTML 文件路径数组
 * @param {string} outputPdfPath - 输出 PDF 路径
 * @param {Object} options - PDF 选项
 * @returns {Promise<void>}
 */
async function convertMultipleHtmlToPdf(htmlFilePaths, outputPdfPath, options = {}) {
  if (htmlFilePaths.length === 0) {
    throw new Error('没有提供 HTML 文件');
  }
  if (htmlFilePaths.length === 1) {
    return await convertSingleHtmlToPdf(htmlFilePaths[0], outputPdfPath, options);
  }
  let browserInstance = null;
  let context = null;
  let page = null;
  try {
    browserInstance = await launchBrowser();
    context = await browserInstance.newContext({
      viewport: { width: 1200, height: 800 },
      ignoreHTTPSErrors: true,
      // 允许访问本地文件
      acceptDownloads: true
    });
    page = await context.newPage();
    
    // 设置页面错误处理
    page.on('pageerror', (error) => {
      // 只显示关键错误，忽略图片加载错误
      if (!error.message.includes('Failed to load resource')) {
        console.log(chalk.yellow(`⚠️  页面错误: ${error.message}`));
      }
    });
    
    page.on('console', (msg) => {
      // 只显示关键错误，忽略图片加载错误
      if (msg.type() === 'error' && !msg.text().includes('Failed to load resource')) {
        console.log(chalk.yellow(`⚠️  控制台错误: ${msg.text()}`));
      }
    });
    
    await fs.ensureDir(path.dirname(outputPdfPath));
    const pdfOptions = {
      path: outputPdfPath,
      format: options.format || 'A4',
      printBackground: options.printBackground !== false,
      margin: options.margin || {
        top: '1cm', right: '1cm', bottom: '1cm', left: '1cm'
      },
      scale: options.scale || 1.0,
      preferCSSPageSize: options.preferCSSPageSize !== false
    };
    
    let combinedHtml = `<!DOCTYPE html><html><head><meta charset="UTF-8"><title>合并的 EPUB 内容</title><style>body{font-family:Arial,sans-serif;line-height:1.6;margin:0;padding:0;}.chapter{page-break-before:always;padding:20px;}.chapter:first-child{page-break-before:avoid;}img{max-width:100%;height:auto;display:block;margin:10px auto;}</style></head><body>`;
    
    for (let i = 0; i < htmlFilePaths.length; i++) {
      const htmlPath = htmlFilePaths[i];
      if (!await fs.pathExists(htmlPath)) continue;
      
      let htmlContent = await fs.readFile(htmlPath, 'utf8');
      // 注意：这里不再调用 processImagePaths，因为 HTML 文件已经在 index.js 中处理过了
      
      const bodyMatch = htmlContent.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
      if (bodyMatch) {
        combinedHtml += `<div class="chapter">${bodyMatch[1]}</div>`;
      } else {
        combinedHtml += `<div class="chapter">${htmlContent}</div>`;
      }
    }
    
    combinedHtml += `</body></html>`;
    
    // 将合并HTML输出到与图片相同的临时目录下
    const tempHtmlDir = path.dirname(htmlFilePaths[0]); // 使用第一个HTML文件所在的目录
    const tempHtmlPath = path.join(tempHtmlDir, `temp_combined_${Date.now()}.html`);
    await fs.writeFile(tempHtmlPath, combinedHtml, 'utf8');
    
    try {
      const fileUrl = `file://${path.resolve(tempHtmlPath)}`;
      console.log(chalk.gray(`📄 加载合并HTML: ${fileUrl}`));
      
      await page.goto(fileUrl, { 
        waitUntil: 'domcontentloaded', 
        timeout: 30000 
      });
      
      // 等待图片加载
      console.log(chalk.gray('⏳ 等待图片加载...'));
      await page.waitForTimeout(1000); // 减少等待时间从2000ms到1000ms
      
      // 检查图片是否加载成功
      const imageCount = await page.evaluate(() => {
        const images = document.querySelectorAll('img');
        let loadedCount = 0;
        images.forEach(img => {
          if (img.complete && img.naturalWidth > 0) {
            loadedCount++;
          }
        });
        return { total: images.length, loaded: loadedCount };
      });
      
      console.log(chalk.cyan(`📊 图片统计: ${imageCount.loaded}/${imageCount.total} 张图片已加载`));
      
      // 优化PDF生成选项
      const optimizedPdfOptions = {
        ...pdfOptions,
        preferCSSPageSize: false, // 禁用CSS页面大小，提高性能
        printBackground: true
      };
      
      await page.pdf(optimizedPdfOptions);
      
    } finally {
      try { await fs.remove(tempHtmlPath); } catch {}
    }
  } catch (error) {
    throw new Error(`合并 HTML 转 PDF 失败: ${error.message}`);
  } finally {
    if (page) { try { await page.close(); } catch {} }
    if (context) { try { await context.close(); } catch {} }
  }
}

/**
 * 生成压缩版 PDF
 * @param {string} originalPdfPath - 原始 PDF 路径
 * @param {string} compressedPdfPath - 压缩 PDF 路径
 * @param {number} quality - 压缩质量 (0-100)
 * @returns {Promise<void>}
 */
async function compressPdf(originalPdfPath, compressedPdfPath, quality = 80) {
  try {
    // 使用 Playwright 重新生成压缩版 PDF
    const browserInstance = await launchBrowser();
    const context = await browserInstance.newContext({
      viewport: { width: 1200, height: 800 }
    });
    const page = await context.newPage();
    
    // 加载原始 PDF 作为 HTML
    const fileUrl = `file://${path.resolve(originalPdfPath)}`;
    await page.goto(fileUrl, { 
      waitUntil: 'domcontentloaded',
      timeout: 10000 
    });
    
    // 设置压缩版 PDF 选项
    const pdfOptions = {
      path: compressedPdfPath,
      format: 'A4',
      printBackground: true,
      margin: {
        top: '1cm',
        right: '1cm',
        bottom: '1cm',
        left: '1cm'
      },
      scale: quality / 100, // 根据质量调整缩放
      preferCSSPageSize: false
    };
    
    await page.pdf(pdfOptions);
    
    await page.close();
    await context.close();
    
  } catch (error) {
    throw new Error(`PDF 压缩失败: ${error.message}`);
  }
}

/**
 * 将 HTML 文件转换为 PDF（兼容旧 API）
 * @param {string|string[]} htmlFilePath - HTML 文件路径或路径数组
 * @param {string} outputPdfPath - 输出 PDF 路径
 * @param {Object} options - PDF 选项
 * @returns {Promise<void>}
 */
async function convertHtmlToPdf(htmlFilePath, outputPdfPath, options = {}) {
  if (isShuttingDown) {
    throw new Error('浏览器正在关闭，无法执行转换');
  }
  
  if (Array.isArray(htmlFilePath)) {
    return await convertMultipleHtmlToPdf(htmlFilePath, outputPdfPath, options);
  } else {
    return await convertSingleHtmlToPdf(htmlFilePath, outputPdfPath, options);
  }
}

/**
 * 生成高清版和压缩版 PDF
 * @param {string|string[]} htmlFilePath - HTML 文件路径或路径数组
 * @param {string} outputDir - 输出目录
 * @param {string} baseName - 基础文件名（不含扩展名）
 * @param {Object} options - PDF 选项
 * @returns {Promise<{hdPath: string, compressedPath: string}>}
 */
async function convertToBothVersions(htmlFilePath, outputDir, baseName, options = {}) {
  const hdPath = path.join(outputDir, `${baseName}_高清版.pdf`);
  const compressedPath = path.join(outputDir, `${baseName}_压缩版.pdf`);
  
  // 并行生成高清版和压缩版PDF
  console.log(chalk.blue(`📄 并行生成高清版和压缩版 PDF...`));
  
  const [hdResult, compressedResult] = await Promise.all([
    convertHtmlToPdf(htmlFilePath, hdPath, { ...options, scale: 1.0 }),
    convertHtmlToPdf(htmlFilePath, compressedPath, { ...options, scale: 0.8 })
  ]);
  
  console.log(chalk.green(`✅ 高清版: ${path.basename(hdPath)}`));
  console.log(chalk.green(`✅ 压缩版: ${path.basename(compressedPath)}`));
  
  return { hdPath, compressedPath };
}

/**
 * 关闭浏览器实例
 */
async function closeBrowser() {
  isShuttingDown = true;
  
  if (browser) {
    try {
      await browser.close();
      browser = null;
    } catch (error) {
      console.log(chalk.yellow(`⚠️  关闭浏览器时出错: ${error.message}`));
    }
  }
}

/**
 * 获取浏览器状态
 */
function getBrowserStatus() {
  return {
    isRunning: browser !== null,
    isShuttingDown
  };
}

module.exports = {
  convertHtmlToPdf,
  convertToBothVersions,
  closeBrowser,
  getBrowserStatus
}; 